// 缓存模块
package xcache

import (
	"fmt"
	"sync"
	"time"

	"gitee.com/xiaoyutab/xgotool/xerror"
	"github.com/gomodule/redigo/redis"
)

// 因xgodb.Cachexxxxx使用稍微有些繁杂，所以此处将缓存模块进一步精简，并逐步废弃xgodb.Cachexxx操作
type Config struct {
	Hosts       string                      // Redis连接地址
	Pass        string                      // redis密码
	RedisSelect uint8                       // redis查询库
	ErrFunc     func(msg string, err error) // Redis报错记录函数，用于记录Redis的报错信息

	// 以下的配置模块为程序内部使用的配置
	Conn        *redis.Pool   // redis连接配置
	CacheSync   sync.Map      // 程序内缓存定时
	Connect     redis.Conn    // redis连接
	DefaultTime time.Duration // 默认缓存时长
}

type RedisType struct {
}

var _default Config = Config{
	CacheSync:   sync.Map{},
	DefaultTime: time.Hour * 2,
}

// 设置redis连接
func Regedit(conf *Config) {
	if conf != nil {
		if conf.Hosts != "" {
			_default.Hosts = conf.Hosts
		}
		if conf.DefaultTime > 0 {
			_default.DefaultTime = conf.DefaultTime
		}
		if conf.RedisSelect > 0 {
			_default.RedisSelect = conf.RedisSelect
		}
		if conf.Pass != "" {
			_default.Pass = conf.Pass
		}
		if conf.ErrFunc != nil {
			_default.ErrFunc = conf.ErrFunc
		}
		_default.Conn = &redis.Pool{
			Dial: func() (redis.Conn, error) {
				return redis.Dial("tcp", _default.Hosts)
			},
		}
	}
}

// 设置连接和密码，需要异步执行_default.Connect.Close()
func open() {
	if _default.Connect == nil {
		_default.Connect = _default.Conn.Get()
	}
	if _default.Pass != "" {
		if _, err := _default.Connect.Do("AUTH", _default.Pass); err != nil {
			errorFunc("缓存库密码认证报错", err)
			_default.Connect = nil
		}
	}
	if _default.Connect != nil && _default.RedisSelect != 0 {
		if _, err := _default.Connect.Do("SELECT", _default.RedisSelect); err != nil {
			errorFunc("缓存库认证失败", err)
			_default.Connect = nil
		}
	}
}

// 执行redis关闭操作
func close() {
	if _default.Connect == nil {
		return
	}
	_default.Connect.Close()
	_default.Connect = nil
}

// 错误返回
//
//	msg	错误概述
//	err	错误详情
func errorFunc(msg string, err error) error {
	if _default.ErrFunc != nil {
		_default.ErrFunc(msg, err)
	}
	return err
}

// 异常恢复函数
//
//	msg	恢复描述关键词
func panic_recover(msg string) {
	if r := recover(); r != nil {
		_default.Connect = nil
		switch err := r.(type) {
		case string:
			errorFunc("Panic "+msg+" 异常-1", xerror.New(err))
		case error:
			errorFunc("Panic "+msg+" 异常-2", err)
		default:
			errorFunc("Panic "+msg+" 异常-3", fmt.Errorf("%T: %v", err, err))
		}
	}
}
